package async;

import java.util.concurrent.locks.LockSupport;

// 10861 ms, r = 4994994047 java --enable-preview -Xlog:gc=info,gc+heap=info:gc_loom.log:time async.LoomTest
//  4373 ms, r = 4995000000 java --enable-preview -Xlog:gc=info,gc+heap=info:gc_loom.log:time -Djdk.virtualThreadScheduler.parallelism=1 async.LoomTest
public class LoomTest {
	private static final int N1 = 100;
	private static final int N2 = 100;
	private static final int N3 = 1000;
	private static final int N = N1 * N2 * N3;
	private static int s_i;
	private static Thread t0, t1;

	private static void f3() {
		for (int i = 0; i < N3; i++) {
			s_i = i;
			LockSupport.unpark(t1);
			LockSupport.park();
		}
	}

	private static void f2() {
		for (int i = 0; i < N2; i++)
			f3();
	}

	private static void f1() {
		for (int i = 0; i < N1; i++)
			f2();
	}

	public static void main(String[] args) throws InterruptedException {
		long t = System.nanoTime();
		long[] r = new long[1];
		var vb = Thread.ofVirtual();
		t0 = vb.unstarted(LoomTest::f1);
		t1 = vb.unstarted(() -> {
			long r1 = 0;
			for (int i = 0; i < N; ++i) {
				LockSupport.park();
				r1 += s_i;
				LockSupport.unpark(t0);
			}
			r[0] = r1;
		});
		t0.start();
		t1.start();
		t1.join();
		System.out.println((System.nanoTime() - t) / 1_000_000 + " ms, r = " + r[0]);
	}
}
